﻿/*
 * ©2009-2010 XELF
 * http://xelf.info
 */

using System;

namespace XELF.Framework {

	/// <summary>
	/// 整数についての補助関数。実用ではない異なる実装。
	/// </summary>
	public static partial class IntHelper {
		/// <summary>
		/// 単位階段関数
		/// </summary>
		/// <param name="x"></param>
		/// <returns></returns>
		public static int UnitStep(int x) {
			return ((2 * x + 1) / Math.Abs(2 * x + 1) + 1) >> 1;
		}
		/// <summary>
		/// x != y
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int IsNotEquals(int x, int y) {
			return UnitStep(Math.Abs(x - y) - 1);
		}
		/// <summary>
		/// x == y
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int IsEquals(int x, int y) {
			return 1 - IsNotEquals(x, y);
		}
		/// <summary>
		/// 最大
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int Max(int x, int y) {
			return (x + y + Math.Abs(x - y)) >> 1;
		}
		/// <summary>
		/// 最小
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int Min(int x, int y) {
			return (x + y - Math.Abs(x - y)) >> 1;
		}
		/// <summary>
		/// x &gt;= y
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int GreaterEquals(int x, int y) {
			return IsEquals(Max(x, y), x);
		}
		/// <summary>
		/// x &lt;= y
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int LessEquals(int x, int y) {
			return IsEquals(Max(x, y), y);
		}
		/// <summary>
		/// x &gt; y
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int GreaterThan(int x, int y) {
			return GreaterEquals(x, y) * IsNotEquals(x, y);
		}
		/// <summary>
		/// x &lt; y
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int LessThan(int x, int y) {
			return LessEquals(x, y) * IsNotEquals(x, y);
		}

		/// <summary>
		/// 割り切れるかどうか確かめる。
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public static int Divisible(int x, int y) {
			return 1 - (Math.Sign(x % y) & 1);
		}
		/// <summary>
		/// 素数かどうか確かめる。
		/// </summary>
		/// <param name="x"></param>
		/// <returns></returns>
		public static int IsPrime(int x) {
			for (int k = 2; k < x; k++) {
				if (Divisible(x, k) != 0) return 0;
			}
			return 1;
		}
		/// <summary>
		/// n番目の素数(n &lt;= 30)
		/// </summary>
		/// <param name="n"></param>
		/// <returns></returns>
		public static int Prime(int n) {
			int numberPrimes = 0;
			int j;
			int end = 1 << n;
			for (j = 2; j < end; j++) {
				numberPrimes += IsPrime(j);
				if (numberPrimes >= n)
					return j;
			}
			return 0;
		}
	}

}
